package com.zhiletu.collect.splitword;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 *
 * @Title: MapSort.java
 * @Package com.zhiletu.collect.splitword
 * @Description: map处理类
 * @author zhiletu.com
 * @date 2021年3月11日
 * @version V1.0
 */
public class MapSort<T extends Comparable<T>> {
	/*public static void main(String[] args) {
		Map<String, WordFilter> map = new TreeMap<String, WordFilter>();
		map.put("中国", new WordFilter("ns","中国", 20));
		map.put("小日本", new WordFilter("ns","小日本", 5));
		map.put("美利坚", new WordFilter("ns","美利坚", 3));
		map.put("匈牙利", new WordFilter("ns","匈牙利",8));
		
		System.out.print("排序前：{begin->");
		for (Map.Entry<String, WordFilter> entry : map.entrySet()) {
			System.out.print("["+entry.getKey() + "->" + entry.getValue().count+"]->");
		}
		System.out.println("over}");
		
		// 实例化一下泛型
		MapSort<WordFilter> mapSort = new MapSort<WordFilter>();
		
		Map<String, WordFilter> resultMap = mapSort.sortMapByValue(map); //按Value进行排序
		
		System.out.print("排序后：{begin->");
		for (Map.Entry<String, WordFilter> entry : resultMap.entrySet()) {
			System.out.print("["+entry.getKey() + "->" + entry.getValue().count+"]->");
		}
		System.out.print("over}");
	}*/

	/**
	 * 使用 Map按任意类型value排序
	 * @param map
	 * @return
	 */
	public Map<String, T> sortMapByValue(Map<String, T> map) {
		if (map == null || map.isEmpty()) {
			return null;
		}
		/*
		 一般情况下，我们用的最多的是HashMap,在Map 中插入、删除和定位元素，HashMap 是最好的选择。但如果您要按自然顺序或自定义顺序遍历键，
		 那么TreeMap会更好。如果需要输出的顺序和输入的相同,那么用LinkedHashMap 可以实现,它还可以按读取顺序来排列.HashMap是一个最常用的Map，
		 它根据键的hashCode值存储数据，根据键可以直接获取它的值，具有很快的访问速度。HashMap最多只允许一条记录的键为NULL，允许多条记录的值为NULL。
		 HashMap不支持线程同步，即任一时刻可以有多个线程同时写HashMap，可能会导致数据的不一致性。如果需要同步，可以用Collections的synchronizedMap
		 搜索方法使HashMap具有同步的能力。Hashtable与HashMap类似，不同的是：它不允许记录的键或者值为空；它支持线程的同步，即任一时刻只有一个线程能写Hashtable，
		 因此也导致了Hashtable在写入时会比较慢。LinkedHashMap保存了记录的插入顺序，在用Iterator遍历LinkedHashMap时，先得到的记录肯定是先插入的。
		 在遍历的时候会比HashMap慢TreeMap能够把它保存的记录根据键排序，默认是按升序排序，也可以指定排序的比较器。当用Iterator遍历TreeMap时，得到的记录是排过序的。
		 */
		Map<String, T> sortedMap = new LinkedHashMap<String, T>();
		List<Entry<String, T>> entryList = new ArrayList<Entry<String, T>>(map.entrySet());
		Collections.sort(entryList, new MapValueComparator<T>());
		Iterator<Entry<String, T>> iter = entryList.iterator();
		Entry<String, T> tmpEntry = null;
		while (iter.hasNext()) {
			tmpEntry = iter.next();
			sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
		}
		// 置空大数据
		entryList = null;

		return sortedMap;
	}
}

/**
 * 针对Map的比较器类
 * @author zhiletu.com
 *
 * @param <T>
 */
class MapValueComparator<T extends Comparable<T>> implements Comparator<Entry<String, T>> {
	@Override
	public int compare(Entry<String, T> o1, Entry<String, T> o2) {
		return o1.getValue().compareTo(o2.getValue());
	}
}